package cn.learn.config;

import cn.learn.properties.LoginResponseType;
import cn.learn.properties.SecurityProperties;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;

/**
 * 成功登录处理器, 可以实现AuthenticationSuccessHandler接口，
 * 继承SavedRequestAwareAuthenticationSuccessHandler的好处是可以缓存之前的访问页面，这个也是spring默认成功处理器
 * <p>
 * 自定了成功、失败处理器，那么失败后就不会自动跳转到失败的原因页面 login?error，除非自己定义路径
 *
 * @author huangyezhan
 * @date 2020年02月14日16:03
 */
@Component
public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
    private static final Logger logger = LoggerFactory.getLogger(MyAuthenticationSuccessHandler.class);

    @Autowired
    private ObjectMapper       objectMapper;
    @Autowired
    private SecurityProperties securityProperties;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
                                        HttpServletResponse response,
                                        Authentication authentication)
            throws IOException, ServletException {
        /**
         * 成功后的操作处理，写自己的业务逻辑
         * getLocalAddr该服务器所在的IP
         * getRemoteAddr客户端所在IP，如果通过了Apache，Squid，Nginx等反向代理软件就不能获取到客户端的真实IP地址了
         */
        logger.info("登录成功的用户账号：[{}]，IP地址：{}", authentication.getName(), request.getRemoteAddr());
        //以json格式返回登录结果
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        Object                                 details     = authentication.getDetails();
        Object                                 credentials = authentication.getCredentials();

        //响应方式方式：json或者redirect
        if (LoginResponseType.JSON.equals(securityProperties.getLoginType())) {
            response.setContentType("application/json;charset=UTF-8");

            //返回内容以后要统一格式，现在先验证看结果，Authentication的内容太多了
            response.getWriter().write(objectMapper.writeValueAsString(authentication));
        } else {
            super.onAuthenticationSuccess(request, response, authentication);
        }

    }

}
